use std::{rc::Rc, cell::RefCell};

use crate::{instructions::base::{self, Instruction, BytecodeReader}, rtda::Frame};

// 把栈顶的两个引用弹出，根据引用是否相同进行跳转。

// Branch if reference comparison succeeds
#[derive(Debug, Default)]
pub struct IF_ACMPEQ {
    offset: i32
}

impl Instruction for IF_ACMPEQ {
    fn fetch_operands(&mut self, reader: &mut BytecodeReader) {
        self.offset = reader.read_i16() as i32;
    }

    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        if _acmp(frame.clone()) {
            base::branch(frame, self.offset)
        }
    }
}

#[derive(Debug, Default)]
pub struct IF_ACMPNE {
    offset: i32
}

impl Instruction for IF_ACMPNE {
    fn fetch_operands(&mut self, reader: &mut BytecodeReader) {
        self.offset = reader.read_i16() as i32;
    }

    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        if !_acmp(frame.clone()) {
            base::branch(frame, self.offset)
        }
    }
}

fn _acmp(frame: Rc<RefCell<Frame>>) -> bool {
	let stack = frame.borrow().get_operand_stack();
    let ref2 = stack.borrow_mut().pop_ref();
    let ref1 = stack.borrow_mut().pop_ref();
    // 通过指针判断 
    match (ref1, ref2) {
        (Some(a), Some(b)) => std::ptr::eq(a, b),
        (None, None) => true,
        _ => false
    }
    // let a = ref1.unwrap().as_ref() as *const _;
    // let b = ref2.unwrap().as_ref() as *const _;
    // a == b
}